package com.sicau.smarttraceplatform.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.concurrent.TimeUnit;

/**
 * @author sxt
 * redis操作工具类
 */
@Slf4j
public class RedisHelper<Obj> {

    /**
     * RedisTemplate对象
     */
    private final RedisTemplate<String, Obj> redisTemplate;

    /**
     * 默认时间单位
     */
    private final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.SECONDS;

    public RedisHelper(RedisTemplate redisTemplate) {
        this.redisTemplate = new RedisTemplate<>();
        BeanUtils.copyProperties(redisTemplate, this.redisTemplate);
        this.redisTemplate.afterPropertiesSet();/*初始化RedisTemplate*/
    }

    /**
     * 添加缓存并设置过期时间
     *
     * @param key      键
     * @param value    值
     * @param timeOut  过期时间
     * @param timeUnit 时间单位
     * @return true添加成功 false添加失败
     */
    public boolean set(String key, Obj value, long timeOut, TimeUnit timeUnit) {
        return doSetValue(key, value, timeOut, timeUnit);
    }


    /**
     * 添加缓存并设置过期时间
     *
     * @param key     键
     * @param value   值
     * @param timeOut 过期时间
     * @return true添加成功 false添加失败
     */
    public boolean set(String key, Obj value, long timeOut) {
        return doSetValue(key, value, timeOut, DEFAULT_TIME_UNIT);
    }


    private boolean doSetValue(String key, Obj value, long timeOut, TimeUnit timeUnit) {
        log.info("redis添加缓存操作, key: {}, value: {}, timeOut: {}", key, value, timeOut);
        if (timeOut > 0) {
            try {
                redisTemplate.opsForValue().set(key, value, timeOut, timeUnit);
                log.info("redis添加缓存操作成功");
                return true;
            } catch (Exception e) {
                log.error("redis添加缓存操作异常, 异常信息为: {}", e.getMessage());
                return false;
            }
        } else {
            return set(key, value);  //调用不设置缓存时效的方法
        }
    }

    /**
     * 添加缓存
     *
     * @param key   键
     * @param value 值
     * @return true添加成功 false添加失败
     */
    public boolean set(String key, Obj value) {
        log.info("redis添加缓存操作, key: {}, value: {}", key, value);
        try {
            redisTemplate.opsForValue().set(key, value);
            log.info("redis添加缓存操作成功");
            return true;
        } catch (Exception e) {
            log.error("redis添加缓存操作异常, 异常信息为: {}", e.getMessage());
            return false;
        }
    }


    /**
     * 获取对象类型缓存
     *
     * @param key 键
     * @return 获取到的缓存对象
     */
    public Obj getExpire(String key) {
        log.info("redis获取缓存操作, key: {}", key);
        if (key == null) {
            log.info("传入的key值为空");
            return null;
        } else {
            Obj obj = null;
            try {
                obj = redisTemplate.opsForValue().get(key);
            } catch (Exception e) {
                log.error("Redis操作出现异常: {}", e.getMessage());
            }
            log.info("redis获取缓存操作完成, 缓存值为: {}", obj);
            return obj;
        }
    }

    /**
     * 删除缓存
     *
     * @param key 键
     */
    @SuppressWarnings("unchecked")
    public void delete(String... key) {
        log.info("redis删除缓存操作, key: {}", (Object[]) key);
        if (key != null) {
            int length = key.length;
            if (length > 0) {
                try {
                    if (length == 1) {
                        redisTemplate.delete(key[0]);
                    } else {
                        redisTemplate.delete(CollectionUtils.arrayToList(key));
                    }
                } catch (Exception e) {
                    log.error("Redis操作出现异常: {}", e.getMessage());
                }
            }
        }
    }

}
